package com.hzw.saas.web.admin.hpc.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.hzw.saas.api.hpc.IHpcAccountSearchService;
import com.hzw.saas.api.hpc.IHpcAccountService;
import com.hzw.saas.api.hpc.bo.HpcAccountBo;
import com.hzw.saas.api.hpc.bo.HpcAccountInfoContractFullBO;
import com.hzw.saas.api.hpc.enums.HpcAccountStatus;
import com.hzw.saas.api.hpc.enums.HpcProviderType;
import com.hzw.saas.common.config.annotation.SysLog;
import com.hzw.saas.common.config.util.AssertUtil;
import com.hzw.saas.common.config.util.ExcelUtils;
import com.hzw.saas.common.config.util.PageParam;
import com.hzw.saas.common.config.util.ValidateList;
import com.hzw.saas.common.util.MapperUtil;
import com.hzw.saas.common.util.SnowFlakeUtil;
import com.hzw.saas.web.admin.hpc.param.HpcAccountParam;
import com.hzw.saas.web.admin.hpc.param.HpcAccountUpdateParam;
import io.swagger.annotations.*;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * HPC账号与用户绑定控制器
 * </p>
 *
 * @author sonam
 * @since 2021/2/23 13:58
 */
@Slf4j
@Api(tags = "HPC/并行HPC账号")
@RestController
@RequiredArgsConstructor
@RequestMapping("/hpc/account")
public class HpcBxController {

    private final IHpcAccountService hpcAccountService;
    private final IHpcAccountSearchService hpcAccountSearchService;

    @PostMapping("/")
    @ApiOperation(value = "添加并行HPC账号", notes = "添加并行HPC账号，支持批量")
    @ApiOperationSort(1)
    @ApiResponses({
        @ApiResponse(code = 200, message = "添加成功")
    })
    @SysLog(operation = "添加并行HPC账号", mode = 3)
    public ResponseEntity<Void> addBatchHcpAccount(@Validated @RequestBody ValidateList<HpcAccountParam> hpcAccountParams) {
        List<HpcAccountBo> hpcAccountBos = new ArrayList<>();
        hpcAccountParams.forEach(hpcAccountParam -> {
            HpcAccountBo hpcAccount = MapperUtil.nf().map(hpcAccountParam, HpcAccountBo.class);
            hpcAccount.setHpcAccountId(String.valueOf(SnowFlakeUtil.nextId()));
            if (hpcAccountParam.getCoreTime() != null) {
                hpcAccount.setCoreTimeAvailable(hpcAccountParam.getCoreTime());
                hpcAccount.setCoreTimeAvailableTotal(hpcAccountParam.getCoreTime());
            }
            hpcAccount.setCreateDate(new Date());
            hpcAccount.setStatus(HpcAccountStatus.NORMAL.value());
            hpcAccount.setLevel(0);
            hpcAccountBos.add(hpcAccount);
        });

        try {
            hpcAccountService.addBatch(hpcAccountBos);
        } catch (DuplicateKeyException e) {
            log.error("添加超算失败", e);
            AssertUtil.assertThrow("添加并行HPC账号失败,存在相同的HPC超算账号。", e, true);
        }
        return ResponseEntity.ok().build();
    }

    @PutMapping("/")
    @ApiOperation(value = "更新并行HPC账号", notes = "更新HPC账号")
    @ApiOperationSort(1)
    @ApiResponses({
        @ApiResponse(code = 200, message = "更新成功")
    })
    @SysLog(operation = "更新并行HPC账号", mode = 3)
    public ResponseEntity<Void> updateHpcAccount(@Validated @RequestBody HpcAccountUpdateParam hpcAccountParams) {
        HpcAccountBo hpcAccountBo = MapperUtil.nf().map(hpcAccountParams, HpcAccountBo.class);
        AssertUtil.assertThrow("更新失败", !hpcAccountService.update(hpcAccountBo));
        return ResponseEntity.ok().build();
    }

    @DeleteMapping("/{hpcAccountId}")
    @ApiOperation(value = "删除并行HPC账号", notes = "删除并行HPC账号")
    @ApiOperationSort(6)
    @SysLog(operation = "删除并行HPC账号", mode = 3)
    public ResponseEntity<Void> deleteHpcAccount(@PathVariable String hpcAccountId) {
        hpcAccountService.delete(hpcAccountId);
        return ResponseEntity.ok().build();
    }

    @SysLog(operation = "查询并行HPC账号列表")
    @GetMapping("/")
    @ApiOperation(value = "查询并行HPC账号列表", notes = "查询HPC账号列表")
    @ApiOperationSort(2)
    public ResponseEntity<IPage<HpcAccountInfoContractFullBO>> searchHpcAccount(PageParam pageParam,
                                                                                @RequestParam(defaultValue = "2") @ApiParam(value = "查询内容,1-未分配,2-已分配,3-已冻结,4-需要补充") Integer type,
                                                                                @RequestParam(required = false) @ApiParam(value = "查询关键字，1|4 关键字为hpc账号名称，2|3 hpc账号名称，客户姓名，手机号码，邮箱") String keyWord,
                                                                                @RequestParam(required = false) @ApiParam(value = "是否绑定合同") Boolean contractBound,
                                                                                @RequestParam(required = false) @ApiParam(value = "等级ID") List<String> levelIds) {
        return ResponseEntity.ok(hpcAccountSearchService.pageHpcAccountInfoContractFull(pageParam, keyWord, type, levelIds, contractBound, null, null, null, HpcProviderType.BX));
    }

    @SneakyThrows
    @ApiOperationSort(2)
    @GetMapping("/export")
    @SysLog(operation = "导出并行HPC账号列表")
    @ApiOperation(value = "导出HPC账号列表", notes = "导出HPC账号列表")
    public ResponseEntity<Void> exportHpcAccount(@RequestParam(defaultValue = "2") @ApiParam(value = "查询内容,1-未分配,2-已分配,3-已冻结,4-需要补充") Integer type,
                                                 @RequestParam(required = false) @ApiParam(value = "查询关键字，1|4 关键字为hpc账号名称，2|3 hpc账号名称，客户姓名，手机号码，邮箱") String keyWord,
                                                 @RequestParam(required = false) @ApiParam(value = "等级ID") List<String> levelIds,
                                                 @RequestParam(required = false) @ApiParam(value = "是否绑定合同") Boolean contractBound,
                                                 @RequestParam(required = false) @ApiParam(value = "HPC-USER-ID") List<String> hpcAccountUserIds, HttpServletResponse response) {
        IPage<HpcAccountInfoContractFullBO> pageData = hpcAccountSearchService .pageHpcAccountInfoContractFull(PageParam.getBigPageParam(), keyWord, type, levelIds, contractBound, null, null, null, HpcProviderType.BX);
        if (Objects.isNull(pageData)) {
            return ResponseEntity.ok().build();
        }
        List<HpcAccountInfoContractFullBO> hpcAccountInfoContractFullDTOS = pageData.getRecords();
        if (CollectionUtils.isNotEmpty(hpcAccountUserIds) && CollectionUtils.isNotEmpty(hpcAccountInfoContractFullDTOS)) {
            hpcAccountInfoContractFullDTOS = hpcAccountInfoContractFullDTOS.stream().filter(data -> hpcAccountUserIds.contains(data.getHpcAccountUserId())).collect(Collectors.toList());
        }
        // TODO 重写DTO
        if (CollectionUtils.isNotEmpty(hpcAccountInfoContractFullDTOS)) {
            ExcelUtils.exportExcel(hpcAccountInfoContractFullDTOS, "HPC账号信息", "HPC账号信息", HpcAccountInfoContractFullBO.class, "HPC账号信息", response);
        }
        return ResponseEntity.ok().build();
    }

}
